package com.android.sms_manager.service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.android.sms_manager.data.MyData;

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.util.Log;

public class QueryService {

	/**
	 * get the whole conversation
	 * @param context
	 * @param uri
	 * @param protocol
	 * @return
	 */
	public static List<Map<String, Object>> getConversation(Context context,
			String uri, int protocol,String querytext) {

		List<Map<String, Object>> list = null;
		String colValue[] = null;
		String keyValue[] = null;
		if(uri.equals(MyData.URI_SMS_ALL)){
			
			colValue = new String[] {
					MyData.COL_ID, 
					MyData.COL_ADDRESS,
					MyData.COL_DATE,
					MyData.COL_THREAD_ID,
					MyData.COL_BODY,
					MyData.COL_MSG_COUNT,
					//MyData.COL_ADDRESS
			};
			keyValue = new String[] { 
					MyData.KEY_ID, 
					MyData.KEY_NAME,
					MyData.KEY_DATE, 
					MyData.KEY_THREAD_ID, 
					MyData.KEY_BODY,
					MyData.KEY_MSG_COUNT,
					MyData.KEY_ADDRESS
			};
			
			
			//	list = getSmsConversation(context, uri, colValue, keyValue,protocol);
			list = getResult(context, uri, colValue, keyValue, protocol, querytext);
		}
		else if(uri.equals(MyData.URI_SMS_DRAFT)){
			colValue = new String[] {
					MyData.COL_ID, 				
					MyData.COL_DATE,
					MyData.COL_BODY,				
			};
			keyValue = new String[] { 
					MyData.KEY_ID, 			
					MyData.KEY_DATE, 					
					MyData.KEY_BODY,				
			};
					
			list = getDraft(context, uri, colValue, keyValue, protocol);
		}
		
		return list;
	}
	/**
	 * Make the diffrent search args by querytext
	 * @param context
	 * @param uri
	 * @param colValue
	 * @param keyValue
	 * @param protocol
	 * @param querytext
	 * @return
	 */
	public static List<Map<String, Object>> getResult(Context context, String uri, String[] colValue, String[] keyValue,
			int protocol,String querytext) {
		
		String selection = null;
		String[] selectionargs = null;
		String[] projection = new String[colValue.length];
		
	
		if(querytext == null){
			//query nothing
			for (int i = 0; i < projection.length; i++)
				if (colValue[i].equals(MyData.COL_MSG_COUNT))
					projection[i] = new String("count(thread_id) as  "
							+ colValue[i]);
				else
					projection[i] = new String(colValue[i]);
			selection = MyData.COL_TYPE+" != 3) group by (thread_id";
			selectionargs = null;
		}
		else{
			//query some words
			for (int i = 0; i < projection.length; i++)
				if (colValue[i].equals(MyData.COL_MSG_COUNT))
					projection[i] = new String("count(_id) as  "
							+ colValue[i]);
				else
					projection[i] = new String(colValue[i]);
			selection = MyData.COL_BODY+" like ? and "+MyData.COL_TYPE+" != 3 ) group by (_id";
			selectionargs = new String[]{"%"+querytext+"%"};		
		}
		
		List<Map<String, Object>> list = getSmsConversations(context, uri, colValue, keyValue,
				protocol,selection,selectionargs,projection);
		return list;
	}
	/**
	 * get all of args, start to search
	 * @param context
	 * @param uri
	 * @param colValue
	 * @param keyValue
	 * @param protocol
	 * @param selection
	 * @param selectionargs
	 * @return
	 */
	private static List<Map<String, Object>> getSmsConversations(
			Context context, String uri, String[] colValue, String[] keyValue,
			int protocol,String selection,String[] selectionargs,String[] projection) {

		List<Map<String, Object>> list = null;
		Uri u = Uri.parse(uri);
		
		ContentResolver cr = context.getContentResolver();
		Cursor cursor = cr.query(u, projection, selection, selectionargs, "date desc");

		if (cursor.getCount() > 0) {
			list = new ArrayList<Map<String, Object>>();
			Map<String, Object> map = null;
			while (cursor.moveToNext()) {
				map = new HashMap<String, Object>();
				for (int i = 0; i < colValue.length; i++)
					if (protocol == MyData.PROTOCOL_SMS
							&& colValue[i].equals(MyData.COL_ADDRESS))
					{						
						//phonenumber,put in keyaddress,and get name into keyname
						map.put(keyValue[colValue.length], cursor.getString(cursor.getColumnIndex(colValue[i])));
						map.put(keyValue[i],
								getContactsNameByAddress(context, cursor
										.getString(cursor
												.getColumnIndex(colValue[i]))));
					}
					else if (colValue[i].equals(MyData.COL_DATE)){
						if(protocol == MyData.PROTOCOL_SMS)
						map.put(keyValue[i], getDate(cursor.getLong(cursor
								.getColumnIndex(colValue[i]))));
					}
					else if(colValue[i].equals(MyData.COL_MSG_COUNT))
						map.put(keyValue[i], "("+cursor.getString(cursor
								.getColumnIndex(colValue[i]))+")");
					else if(colValue[i].equals(MyData.COL_ID))
						map.put(keyValue[i], cursor.getInt(cursor
								.getColumnIndex(colValue[i])));
					else if(colValue[i].equals(MyData.COL_THREAD_ID))
						map.put(keyValue[i], cursor.getInt(cursor
								.getColumnIndex(colValue[i])));
					else
						map.put(keyValue[i], cursor.getString(cursor
								.getColumnIndex(colValue[i])));
				//when sms is draft,address is null,skip this one map.
				if(map.get(MyData.KEY_NAME) == null)
					continue;
				
				list.add(map);
			}
		}
		cursor.close();
		return list;
	}
	/**
	 * Get all draft sms
	 * @param context
	 * @param uri
	 * @param colValue
	 * @param keyValue
	 * @param protocol
	 * @return
	 */
	private static List<Map<String, Object>> getDraft(
			Context context, String uri, String[] colValue, String[] keyValue,
			int protocol) {

		List<Map<String, Object>> list = null;
		String selection = null;
		String[] selectionargs = null;
		String[] projection = new String[colValue.length];

		for(int i=0; i<projection.length; i++)
				projection[i] = new String(colValue[i]);

		ContentResolver cr = context.getContentResolver();
		Uri u = Uri.parse(uri);
		Cursor cursor = cr.query(u, projection, selection, selectionargs, "date desc");
		if (cursor.getCount() > 0) {
			list = new ArrayList<Map<String, Object>>();
			Map<String, Object> map = null;
			while (cursor.moveToNext()) {
				map = new HashMap<String, Object>();
				for (int i = 0; i < colValue.length; i++)
					 if (colValue[i].equals(MyData.COL_DATE))						
						map.put(keyValue[i], getDate(cursor.getLong(cursor
								.getColumnIndex(colValue[i]))));
						
					else if(colValue[i].equals(MyData.COL_ID))
						map.put(keyValue[i], cursor.getInt(cursor
								.getColumnIndex(colValue[i])));
					
					else
						map.put(keyValue[i], cursor.getString(cursor
								.getColumnIndex(colValue[i])));
				
				list.add(map);
			}
		}
		cursor.close();
		return list;
	}

	private static String getDate(long date){
		//notice the format
		SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd HH:mm");
        Date d = new Date(date);    
        return dateFormat.format(d);  
	}
	

	/**
	 * 
	 * Get the name in contacts by the address,if there is nobody,use the address display.
	 * @param context
	 * @param address
	 * @return
	 */
	private static String getContactsNameByAddress(Context context,
			String address) {
		
		if(address == null){
			return null;
		}
		else{
		String name = address;
		String pro[] = new String[] { Phone.DISPLAY_NAME, Phone.NUMBER };
		Uri up = Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, address);
		Cursor c = context.getContentResolver()
				.query(up, pro, null, null, null);
		if (c.moveToFirst())
			name = (c.getString(c.getColumnIndex(Phone.DISPLAY_NAME)));
		else {
			if (address.contains("+86")) {
				up = Uri.withAppendedPath(Phone.CONTENT_FILTER_URI,
						address.replace("+86", ""));
			} else if (!address.contains("+86")) {
				up = Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "+86"
						+ address);
			}
			c = context.getContentResolver().query(up, pro, null, null, null);
			if (c.moveToFirst())
				name = (c.getString(c.getColumnIndex(Phone.DISPLAY_NAME)));
		}
		c.close();
		return name;
		}
	}
	
	
	/**
	 * Get all context in conversation by thread_id
	 * @param context
	 * @param uri
	 * @param thread_id
	 * @param protocol
	 * @return
	 */
	public static List<Map<String,Object>> getAllSmsByThread_id(Context context,
			String uri,int thread_id,int protocol){
		List<Map<String,Object>>list = null;
		list = getSMSByThread_id(context,uri,thread_id);
		
		return list;
	}
	/**
	 * the sms context by thread_id
	 * @param context
	 * @param uri
	 * @param thread_id
	 * @return
	 */
	private static List<Map<String,Object>> getSMSByThread_id(Context context,
			String uri,int thread_id){
		List<Map<String,Object>>list = null;
		
		String pro [] = new String[]{
				MyData.COL_DATE,
				MyData.COL_BODY,
				MyData.COL_ID,
				MyData.COL_TYPE};
		Cursor c = context.getContentResolver().query(Uri.parse(uri), pro,
				"thread_id = ? and type != 3", new String[]{thread_id+""}, "date asc");
		
		if(c.getCount()>0){
			Map<String,Object>map = null;
			list = new ArrayList<Map<String,Object>>();
			while(c.moveToNext()){
				map = new HashMap<String,Object>();
				map.put(MyData.KEY_ID, c.getInt(c.getColumnIndex(MyData.COL_ID)));
				map.put(MyData.KEY_BODY, c.getString(c.getColumnIndex(MyData.COL_BODY)));
				map.put(MyData.KEY_DATE, 
						getDate(c.getLong(c.getColumnIndex(MyData.COL_DATE))));
				map.put(MyData.KEY_TYPE, c.getInt(c.getColumnIndex(MyData.COL_TYPE)));
				list.add(map);
			
				//Log.i("msmservice map", map.get(SData.KEY_ID).toString()+","+map.get(SData.KEY_TYPE).toString());
			}
		}
		c.close();
		return list;
	}

	/**
	 * Delete all conversation by thread_id
	 * @param context
	 * @param thread_id
	 * @param type
	 * @param protocol
	 */
	public static void deleteByThread_id(Context context,int thread_id,int type,int protocol){
		delete(context,MyData.COL_THREAD_ID,thread_id,type,protocol);
	}
	
	/**
	 * Delete a sms by _id
	 * @param context
	 * @param _id
	 * @param type 
	 * @param protocol 
	 */
	public static void deleteById(Context context,int _id,int type,int protocol){
		delete(context,MyData.COL_ID,_id,type,protocol);
	}
	
	/**
	 * Delete a sms by column name
	 * @param context
	 * @param col_name
	 * @param col_value
	 * @param type
	 * @param protocol
	 */
	public static void delete(Context context,String col_name,int col_value,int type,
			int protocol){
		
		context.getContentResolver().delete(
				Uri.parse(MyData.URI_SMS_ALL),
				col_name+" = ?",
				new String[]{String.valueOf(col_value)});
		Log.i("delete", "col_name = "+col_value);
		
	}
}
